#ifndef __MY_UTIL__
#define __MY_UTIL__
#include <iostream>
#include <fstream>
#include <sstream>
#include <memory>
#include <string>
#include <unistd.h>
#include <sys/stat.h>
#include </usr/include/jsoncpp/json/json.h>

namespace aod{
    class FileUtil{
        private:
            std::string _name;//文件路径名称
        public:
            FileUtil(const std::string &name):_name(name){}; 
            bool Exists()//判断文件是否存在 access
            {
                //access的F_OK专门用于检测文件是否存在 -- 存在返回0
                int ret = access(_name.c_str(),F_OK);
                if(ret!=0){
                    std::cerr<<"file is not exits"<<std::endl;
                    return false;
                }
                return true;
            }
            size_t FileSize()//获取文件大小 stat
            {
                if(this->Exists()==false){
                    std::cout<<"file is not exits"<<std::endl;
                    return 0;
                }
                struct stat st;
                //stat接口用于获取文件属性，其中 st_size 就是文件大小成员
                int ret = stat(_name.c_str(),&st);
                if(ret!=0){
                    std::cerr<<"get file stat failed!"<<std::endl;
                }
                return st.st_size;
            }
            bool GetContent(std::string *content)//把_name文件的数据读取到content ifstream
            {
                std::ifstream ifs;
                ifs.open(_name,std::ios::binary);
                if(ifs.is_open() == false){
                    std::cerr<<"open file failed!"<<std::endl;
                    return false;
                }
                size_t flen = this->FileSize();
                content->resize(flen);
                //这里不能content->c_str()因为返回是const的
                //我们这里利用对象然后取地址返回的就是非const的
                ifs.read(&(*content)[0],flen);    
                if(ifs.good()==false){
                    std::cerr<<"read file content failed!"<<std::endl;
                    ifs.close();
                    return false;
                }
                ifs.close();
                return true;
            }
            bool SetContent(const std::string content)//把contrnt数据写入到_name文件 ofstream
            {
                std::ofstream ofs;
                ofs.open(_name,std::ios::binary);
                if(ofs.is_open() == false){
                    std::cerr<<"open file failed!"<<std::endl;
                    return false;
                }
                ofs.write(content.c_str(),content.size());    
                if(ofs.good()==false){
                    std::cerr<<"write file content failed!"<<std::endl;
                    ofs.close();
                    return false;
                }
                ofs.close();
                return true;
            }
            bool CreateDirectory()//针对目录时创建目录 mkdir
            {
                if(this->Exists()){
                    return true;
                }
                mkdir(_name.c_str(),0777);
                return true;
            }
    };

    class JsonUtil{
        public:
        static bool Serialize(const Json::Value value,std::string *body)
        {
            Json::StreamWriterBuilder swb;
            std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

            std::stringstream ss;
            int ret = sw->write(value,&ss);
            if(ret!=0){
                std::cerr<<"Serialize failed!"<<std::endl;
                return false;
            }
            *body = ss.str();
            return true;
        }

        static bool UnSerialize(const std::string body,Json::Value *value)
        {
            Json::CharReaderBuilder crb;
            std::unique_ptr<Json::CharReader> cr(crb.newCharReader());

            std::string err;
            bool ret = cr->parse(body.c_str(),body.c_str()+body.size(),value,&err);
            if(ret==false){
                std::cerr<<"UnSerialize failed!"<<std::endl;
                std::cerr<<err<<std::endl;
                return false;
            }
            return true;
        }
    };
}

#endif